package com.penghaisoft.microwms.product.service.impl;

import com.penghaisoft.microwms.common.Constant;
import com.penghaisoft.microwms.common.data.model.ProScrapOut;
import com.penghaisoft.microwms.common.data.model.ProScrapOutSn;
import com.penghaisoft.microwms.common.dto.ProScrapOutDto;
import com.penghaisoft.microwms.common.dto.Resp;
import com.penghaisoft.microwms.common.dto.TransResult;
import com.penghaisoft.microwms.common.page.Pager;
import com.penghaisoft.microwms.common.service.BaseService;
import com.penghaisoft.microwms.common.wms.model.ProStorageSn;
import com.penghaisoft.microwms.product.dao.ProScrapOutMapper;
import com.penghaisoft.microwms.product.dao.ProScrapOutSnMapper;
import com.penghaisoft.microwms.product.dao.ProStorageSnMapper;
import com.penghaisoft.microwms.product.service.IProScrapOutService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;

/**
 * <p>
 * 业务逻辑实现类
 * </p>
 *
 * @author
 * @createDate
 **/
@Service("proScrapOutService")
public class ProScrapOutServiceImpl extends BaseService implements IProScrapOutService {

    @Autowired
    private ProScrapOutMapper proScrapOutMapper;

    @Autowired
    private ProScrapOutSnMapper proScrapOutSnMapper;

    @Autowired
    private ProStorageSnMapper proStorageSnMapper;

    /**
     * 新增记录
     *
     * @param proScrapOut
     * @return
     */
    @Override
    public Resp create(ProScrapOut proScrapOut) {
        proScrapOutMapper.create(proScrapOut);
        return success();
    }

    /**
     * 删除记录（逻辑删除）
     *
     * @param proScrapOut
     * @return
     */
    @Override
    public Resp delete(ProScrapOut proScrapOut) {
        proScrapOutMapper.delete(proScrapOut);
        return success();
    }

    /**
     * 查询列表
     *
     * @param page
     * @param condition
     * @return
     */
    @Override
    public Pager<ProScrapOut> findListByCondition(int page, int rows, ProScrapOut condition) {
        Pager<ProScrapOut> pager = new Pager<>();
        pager.setPage(page);
        pager.setRows(rows);
        condition.preQuery();
        long size = proScrapOutMapper.queryCount(condition);
        List<ProScrapOut> records = new ArrayList<>();
        if (size > 0) {
            records = proScrapOutMapper.queryList(pager, condition);
        }
        pager.setRecords(records);
        pager.setTotalCount(size);
        return pager;
    }

    /**
     * 查询单条
     *
     * @param id
     * @return
     */
    @Override
    public ProScrapOut findById(String id) {
        return proScrapOutMapper.queryById(id);
    }

    /**
     * 修改记录
     *
     * @param proScrapOut
     * @return
     */
    @Override
    public Resp update(ProScrapOut proScrapOut) {
        proScrapOutMapper.updateBySelect(proScrapOut);
        return success();
    }

    /**
     * @param list
     * @param scrapOutNo
     * @param loginName
     * @return
     * @wzhg 18614 成品手工出库单创建
     */
    @Override
    public Resp insert(List<ProScrapOut> list, String scrapOutNo, String loginName) {
        Date now = new Date();
        HashSet<String> allSet = new HashSet<String>();
        for (int i = 0; i < list.size(); i++) {
            ProScrapOut scrapOut = list.get(i);

            StringBuffer uniqueStr = new StringBuffer("");
            uniqueStr.append(scrapOut.getModel());
            uniqueStr.append(scrapOut.getModelType());
            if (allSet.contains(uniqueStr.toString())) {
                Resp resp = new Resp();
                resp.setCode(Constant.FAIL);
                resp.setMsg("选择的型号、型号类型重复");
                return resp;
            } else {
                allSet.add(uniqueStr.toString());
            }
        }
        for (int i = 0; i < list.size(); i++) {
            ProScrapOut scrapOut = list.get(i);

//    		合同编号、型号、型号类型、需求数量 页面传递的参数已经提供
            scrapOut.setScrapOutNo(scrapOutNo);
            scrapOut.setActiveFlag("1");
            scrapOut.setGmtCreate(now);
            scrapOut.setCreateBy(loginName);
//    		0新建 1入库中 2入库完成
            scrapOut.setScrapOutStatus("0");
            scrapOut.setRealAmount(new BigDecimal(0));

            proScrapOutMapper.create(scrapOut);
        }

        return success();
    }

    @Override
    public Resp loadBill(ProScrapOut proScrapOut) {
        Resp resp = new Resp();

        proScrapOut.setActiveFlag("1");
        List<ProScrapOut> list = proScrapOutMapper.queryByAny(proScrapOut);

        if (list == null || list.isEmpty()) {
            resp.setCode(Constant.FAIL);
            resp.setMsg("该手工出库单号不存在");
        } else {
            Boolean flag_all_2 = true;
            for (ProScrapOut tmp : list) {
//				0新建 1出库中 2出库完成
                if (!"2".equals(tmp.getScrapOutStatus())) {
                    flag_all_2 = false;
                }
            }

            if (flag_all_2) {
                resp.setCode(Constant.FAIL);
                resp.setMsg("该手工出库单已经发货完成！");
                return resp;
            }

            resp.setCode(Constant.SUCCESS);
            resp.setMsg("提单成功");
        }

        return resp;
    }

    /**
     * @param condition
     * @return
     * @Title queryListByAny
     * @Description 根据出库单号查询数据
     * @copy luoteng @edit wzhg
     * @date 2018年6月13日:下午4:49:07
     */
    @Override
    public List<ProScrapOut> queryListByAny(ProScrapOut condition) {
        return proScrapOutMapper.queryByAny(condition);
    }

    /**
     * @param proScrapOutDto
     * @return
     * @Title handInScanBarcode
     * @Description 出库扫码
     * @copy luoteng @edit wzhg
     * @date 2018年6月14日:下午2:01:42
     */
    @Override
    public TransResult scrapOutScanBarcode(ProScrapOutDto proScrapOutDto) {
        TransResult result = new TransResult();
        result.setCode(Constant.SUCCESS);

        Date now = new Date();

        ProStorageSn proStorageSn = new ProStorageSn();
        proStorageSn.setBarcode(proScrapOutDto.getBarcode());
        proStorageSn.setActiveFlag("1");

        List<ProStorageSn> storageList = proStorageSnMapper.queryByAny(proStorageSn);
        if (storageList == null || storageList.isEmpty()) {
            result.setCode(Constant.FAIL);
            result.setMsg("该成品条码不存在。");
            return result;
        } else if (storageList.size() > 1) {
            result.setCode(Constant.FAIL);
            result.setMsg("该成品条码重复。");
            return result;
        } else {
            ProStorageSn storageSnTmp = storageList.get(0);

//        	0：可用 1：冻结 2：已出库 3：抽检冻结
            if (storageSnTmp.getBarcodeStatus() == null) {
                result.setCode(Constant.FAIL);
                result.setMsg("该条码状态为空。");
                return result;
            } else if (storageSnTmp.getBarcodeStatus().equals("2")) {
                result.setCode(Constant.FAIL);
                result.setMsg("该条码已出库。");
                return result;
            } else if (storageSnTmp.getBarcodeStatus().equals("1") || storageSnTmp.getBarcodeStatus().equals("3")) {
                result.setCode(Constant.FAIL);
                result.setMsg("该条码已冻结。");
                return result;
            } else if (storageSnTmp.getBarcodeStatus().equals("0")) {
                ProScrapOutSn proScrapOutSn = new ProScrapOutSn();
                proScrapOutSn.setBarcode(proScrapOutDto.getBarcode());
                proScrapOutSn.setActiveFlag("1");

                List<ProScrapOutSn> scrapOutSnList = proScrapOutSnMapper.queryByAny(proScrapOutSn);
                if (scrapOutSnList != null && !scrapOutSnList.isEmpty()) {
                    result.setCode(Constant.FAIL);
                    result.setMsg("该条码已经扫描，不能再次扫描!");
                    return result;
                } else {
                    ProScrapOut proScrapOut = new ProScrapOut();
                    proScrapOut.setScrapOutNo(proScrapOutDto.getScrapOutNo());
                    proScrapOut.setContractNo(proScrapOutDto.getContractNo());
                    proScrapOut.setModel(storageSnTmp.getModel());
                    proScrapOut.setModelType(storageSnTmp.getModelType());
                    proScrapOut.setActiveFlag("1");

                    List<ProScrapOut> scrapOutList = proScrapOutMapper.queryByAny(proScrapOut);
                    if (scrapOutList == null || scrapOutList.isEmpty()) {
                        result.setCode(Constant.FAIL);
                        result.setMsg("该条码不是出库单所需型号!");
                        return result;
                    } else {
                        ProScrapOut scrapOutTmp = scrapOutList.get(0);
                        if (!scrapOutTmp.getContractNo().equals(storageSnTmp.getContractNo())) {
                            result.setCode(Constant.FAIL);
                            result.setMsg("该条码合同号（" + storageSnTmp.getContractNo() + "）与该手工出库单的合同号（" + scrapOutTmp.getContractNo() + "）不相同!");
                            return result;
                        }
                        List<ProScrapOut> rtnList = new ArrayList<>();

                        // 需求数量
                        BigDecimal requireAmount = scrapOutTmp.getRequireAmount() == null ? BigDecimal.ZERO : scrapOutTmp.getRequireAmount();
                        // 已发数量
                        BigDecimal realAmount = scrapOutTmp.getRealAmount() == null ? BigDecimal.ZERO : scrapOutTmp.getRealAmount();

                        BigDecimal stgamount = storageSnTmp.getAmount() == null ? BigDecimal.ZERO : storageSnTmp.getAmount();

                        BigDecimal val = (realAmount.add(stgamount)).subtract(requireAmount);

                        BigDecimal realtmp = new BigDecimal(0);
                        realtmp = realAmount;
                        int b = val.compareTo(Constant.PRO_MAX_STATIC_METER);

                        Boolean typeFlag = isProLength(storageSnTmp.getModelType());

                        if (realAmount.compareTo(requireAmount) == 0
                                || requireAmount.compareTo(realAmount) < 0) {
                            result.setCode(Constant.FAIL);
                            result.setMsg("该型号已经扫码完成，无需继续扫码!");
                            return result;
                        }else if (typeFlag && b > 0) {
                            result.setCode(Constant.FAIL);
                            result.setMsg("该物料长度过长(实发数量只允许最多超过需求数量" + Constant.PRO_MAX_STATIC_METER + "米)!");
                            return result;
                        } else {
//							0新建 1出库中 2出库完成
                            scrapOutTmp.setScrapOutStatus("1");
                            scrapOutTmp.setLastModifiedBy(proScrapOutDto.getLoginName());
                            scrapOutTmp.setGmtModified(now);
//							更新数量的sql 去掉realAmout的更新
                            scrapOutTmp.setRealAmount(null);

                            if (typeFlag) {
                                scrapOutTmp.setRealAmountAdd(storageSnTmp.getAmount());
                                realAmount = realAmount.add(storageSnTmp.getAmount());
                            } else {
                                scrapOutTmp.setRealAmountAdd(new BigDecimal(1));
                                realAmount = realAmount.add(new BigDecimal(1));
                            }
                        }

//                        realtmp = realtmp.add(new BigDecimal(1));
//                        scrapOutTmp.setRealAmount(realtmp);
                        Integer rtVal = proScrapOutMapper.updateBySelect(scrapOutTmp);
                        if (rtVal != 1) {
                            throw new RuntimeException("扫描条码失败，更新条数存在问题!");
                        }

//						该实发数量只是提供给手持显示，后台sql加数量
                        scrapOutTmp.setRealAmount(realAmount);
//						返回给手持数据
                        rtnList.add(scrapOutTmp);
                        result.setList(rtnList);

//                        ProScrapOut yzOb = new ProScrapOut();
//                        yzOb.setScrapOutId(scrapOutTmp.getScrapOutId());
//                        List<ProScrapOut> yzList = proScrapOutMapper.queryByAny(yzOb);
//
//                        BigDecimal maxRealAmout = requireAmount.add(Constant.PRO_STATIC_METER);
//                        if (modelType.equals(Constant.PRO_MODEL_TYPE_WT) || modelType.equals(Constant.PRO_MODEL_TYPE_ST)
//                                || modelType.equals(Constant.PRO_MODEL_TYPE_BJ) || modelType.equals(Constant.PRO_MODEL_TYPE_G)
//                                || modelType.equals(Constant.PRO_MODEL_TYPE_C)) {
//                            if (yzList.get(0).getRequireAmount().compareTo(yzList.get(0).getRealAmount()) < 0) {
//                                throw new RuntimeException("该型号已经扫码完成，无需继续扫码!");
//                            }
//                        } else {
//                            if (maxRealAmout.compareTo(yzList.get(0).getRealAmount()) < 0) {
//                                throw new RuntimeException("该型号已经扫码完成，无需继续扫码!");
//                            }
//                        }

                        ProScrapOutSn scrapOutSnInsertOb = new ProScrapOutSn();
                        scrapOutSnInsertOb.setScrapOutId(scrapOutTmp.getScrapOutId());
                        scrapOutSnInsertOb.setScrapOutNo(scrapOutTmp.getScrapOutNo());
                        scrapOutSnInsertOb.setContractNo(scrapOutTmp.getContractNo());
                        scrapOutSnInsertOb.setBarcode(proScrapOutDto.getBarcode());
                        scrapOutSnInsertOb.setModel(scrapOutTmp.getModel());
                        scrapOutSnInsertOb.setModelDesc(scrapOutTmp.getModelDesc());
                        scrapOutSnInsertOb.setModelType(scrapOutTmp.getModelType());
                        scrapOutSnInsertOb.setType(scrapOutTmp.getType());
                        scrapOutSnInsertOb.setAmount(storageSnTmp.getAmount());
                        scrapOutSnInsertOb.setUnit(storageSnTmp.getUnit());
                        scrapOutSnInsertOb.setWlCode(storageSnTmp.getWlCode());
                        scrapOutSnInsertOb.setActiveFlag("1");
                        scrapOutSnInsertOb.setGmtCreate(now);
                        scrapOutSnInsertOb.setCreateBy(proScrapOutDto.getLoginName());

                        proScrapOutSnMapper.create(scrapOutSnInsertOb);

//						0：可用 1：冻结 2：已出库 3：抽检冻结
                        storageSnTmp.setBarcodeStatus("2");
                        // 1 报废出库
                        storageSnTmp.setUserDefined1("1");
                        storageSnTmp.setLastModifiedBy(proScrapOutDto.getLoginName());
                        storageSnTmp.setGmtModified(now);

                        Integer rtVal1 = proStorageSnMapper.updateByBarcodeStatus0(storageSnTmp);
                        if (rtVal1 != 1) {
                            throw new RuntimeException("当前条码已经出库，或者被冻结！");
                        }
                    }
                }

            }
        }

        return result;
    }

    /**
     * @param proScrapOutDto
     * @return
     * @Title handInComplete
     * @Description 确认完成
     * @copy luoteng @edit wzhg
     * @date 2018年6月15日:下午3:03:22
     */
    @Override
    public TransResult scrapOutComplete(ProScrapOutDto proScrapOutDto) {
        TransResult result = new TransResult();
        result.setCode(Constant.SUCCESS);

        Date now = new Date();

        ProScrapOut proScrapOut = new ProScrapOut();
        proScrapOut.setActiveFlag("1");
        proScrapOut.setScrapOutNo(proScrapOutDto.getScrapOutNo());

        List<ProScrapOut> scrapOutList = proScrapOutMapper.queryByAny(proScrapOut);
        if (scrapOutList == null || scrapOutList.isEmpty()) {
            result.setCode(Constant.FAIL);
            result.setMsg("该手工出库单不存在!");
            return result;
        } else {
            for (ProScrapOut tmp : scrapOutList) {
                // 需求数量
                BigDecimal requireAmount = tmp.getRequireAmount() == null ? BigDecimal.ZERO : tmp.getRequireAmount();
                // 已发数量
                BigDecimal realAmount = tmp.getRealAmount() == null ? BigDecimal.ZERO : tmp.getRealAmount();

//                BigDecimal maxRealAmout = Constant.PRO_STATIC_METER.add(requireAmount);

                if (requireAmount.compareTo(realAmount) > 0) {
                    result.setCode(Constant.FAIL);
                    result.setMsg("该出库单未扫码完毕!");
                    return result;
                }
//                else if (maxRealAmout.compareTo(realAmount) < 0) {
//                    result.setCode(Constant.FAIL);
//                    result.setMsg("该出库单扫码数量超过需求数量!");
//                    return result;
//                }
            }

            ProScrapOutSn snTmp = new ProScrapOutSn();
            snTmp.setScrapOutNo(proScrapOutDto.getScrapOutNo());
            //			 查询出库单开始、结束扫描时间
            ProScrapOutSn sn = proScrapOutSnMapper.selectBeginEndScanTime(snTmp);

            ProScrapOut upOb = new ProScrapOut();
            upOb.setScrapOutNo(proScrapOutDto.getScrapOutNo());
            upOb.setScanTimeBegin(sn.getScanTimeBegin());
            upOb.setScanTimeEnd(sn.getScanTimeEnd());
            //			0新建 1出库中 2出库完成
            upOb.setScrapOutStatus("2");
            upOb.setLastModifiedBy(proScrapOutDto.getLoginName());
            upOb.setGmtModified(now);

            proScrapOutMapper.updateByScrapOutNo(upOb);
        }

        return result;
    }


    /**
     * @Title scrapOutDelBarcode
     * @Description 删除条码
     * @copy luoteng @edit wzhg
     * @date 2018年6月14日:下午5:25:02
     * @param proScrapOutDto
     * @return
     */
    @Transactional
    @Override
    public TransResult scrapOutDelBarcode(ProScrapOutDto proScrapOutDto){
        TransResult result = new TransResult();
        result.setCode(Constant.SUCCESS);

        Date now = new Date();

        ProStorageSn proStorageSn = new ProStorageSn();
        proStorageSn.setBarcode(proScrapOutDto.getBarcode());
//    	0：可用 1：冻结 2：已出库 3：抽检冻结
        proStorageSn.setBarcodeStatus("2");
        proStorageSn.setActiveFlag("1");

        List<ProStorageSn> storageList = proStorageSnMapper.queryByAny(proStorageSn);
        if(storageList == null || storageList.isEmpty()){
            result.setCode(Constant.FAIL);
            result.setMsg("该成品条码不存在或未出库。");
            return result;
        }else if(storageList.size() > 1){
            result.setCode(Constant.FAIL);
            result.setMsg("该成品条码重复。");
            return result;
        }else{
            ProStorageSn storageSnTmp = storageList.get(0);

            ProScrapOutSn proScrapOutSn = new ProScrapOutSn();
            proScrapOutSn.setScrapOutNo(proScrapOutDto.getScrapOutNo());
            proScrapOutSn.setBarcode(proScrapOutDto.getBarcode());
            proScrapOutSn.setActiveFlag("1");

            List<ProScrapOutSn> scrapOutSnList = proScrapOutSnMapper.queryByAny(proScrapOutSn);
            if(scrapOutSnList == null || scrapOutSnList.isEmpty()){
                result.setCode(Constant.FAIL);
                result.setMsg("该条码未扫描!");
                return result;
            }else{
                ProScrapOutSn proScrapOutSnTmp = scrapOutSnList.get(0);

                ProScrapOut proScrapOut = new ProScrapOut();
                proScrapOut.setScrapOutNo(proScrapOutDto.getScrapOutNo());
                proScrapOut.setContractNo(storageSnTmp.getContractNo());
                proScrapOut.setModel(storageSnTmp.getModel());
                proScrapOut.setModelType(storageSnTmp.getModelType());
                proScrapOut.setActiveFlag("1");

                List<ProScrapOut> scrapOutList = proScrapOutMapper.queryByAny(proScrapOut);
                if (scrapOutList == null || scrapOutList.isEmpty()) {
                    result.setCode(Constant.FAIL);
                    result.setMsg("条码型号与出库单所需型号不一致!");
                    return result;
                }else{
                    ProScrapOut scrapOutTmp = scrapOutList.get(0);
                    List<ProScrapOut> rtnList = new ArrayList<ProScrapOut>();

                    // 需求数量
                    BigDecimal requireAmount = scrapOutTmp.getRequireAmount() ==null ? BigDecimal.ZERO : scrapOutTmp.getRequireAmount();
                    // 已发数量
                    BigDecimal realAmount = scrapOutTmp.getRealAmount() == null ? BigDecimal.ZERO : scrapOutTmp.getRealAmount();

//					C-STG-L:塑套钢-螺旋钢管 C-STG-W:塑套钢-无缝钢管 C-GTG-L:钢套钢-螺旋钢管 C-GTG-W:钢套钢-无缝钢管 C-BLG-L:玻璃钢-螺旋钢管 C-BLG-W:玻璃钢-无缝钢管 C-W:弯头 C-ST:三通 C-BJ:变径 C-G:固定支架
                    String modelType = scrapOutTmp.getModelType() == null ? "" : scrapOutTmp.getModelType();

//					0新建 1入库中 2入库完成
                    scrapOutTmp.setScrapOutStatus("1");
                    scrapOutTmp.setLastModifiedBy(proScrapOutDto.getLoginName());
                    scrapOutTmp.setGmtModified(now);

                    if(modelType.equals(Constant.PRO_MODEL_TYPE_WT) || modelType.equals(Constant.PRO_MODEL_TYPE_ST)
                            || modelType.equals(Constant.PRO_MODEL_TYPE_BJ) || modelType.equals(Constant.PRO_MODEL_TYPE_G)){
                        scrapOutTmp.setRealAmountDel(new BigDecimal(1));
                        realAmount = realAmount.subtract(new BigDecimal(1));
                    }else{
                        scrapOutTmp.setRealAmountDel(storageSnTmp.getAmount());
                        realAmount = realAmount.subtract(storageSnTmp.getAmount());
                    }

                    Integer rtVal = proScrapOutMapper.updateBySelect(scrapOutTmp);
                    if(rtVal != 1){
                        throw new RuntimeException("删除条码失败，更新条数存在问题!");
                    }

//					该实发数量只是提供给手持显示，后台sql加数量
                    scrapOutTmp.setRealAmount(realAmount);
//					返回给手持数据
                    rtnList.add(scrapOutTmp);
                    result.setList(rtnList);

                    proScrapOutSnTmp.setActiveFlag("0");
                    proScrapOutSnTmp.setLastModifiedBy(proScrapOutDto.getLoginName());
                    proScrapOutSnTmp.setGmtModified(now);

                    Integer rtVal1 = proScrapOutSnMapper.updateBySelect(proScrapOutSnTmp);
                    if(rtVal1 != 1){
                        throw new RuntimeException("删除条码失败，更新条数存在问题!");
                    }

//					0：可用 1：冻结 2：已出库 3：抽检冻结
                    storageSnTmp.setBarcodeStatus("0");
                    storageSnTmp.setLastModifiedBy(proScrapOutDto.getLoginName());
                    storageSnTmp.setGmtModified(now);

                    Integer rtVal2 = proStorageSnMapper.updateByBarcodeStatus2(storageSnTmp);
                    if(rtVal2 != 1){
                        throw new RuntimeException("删除条码失败，更新条数存在问题!");
                    }
                }
            }
        }

        return result;
    }

}
